using Dapper;
using DapperExtensions;
using SmartLink.Domain.Entity;
using SmartLink.Domain.ExpandEntity;
using SmartLink.DTOS.Permission;
using SmartLink.EnumLibrary;
using SmartLink.Infrastructure.Cache;
using SmartLink.IRepository;
using SmartLink.Repository.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SmartLink.Repository
{
    public class PER_ActionAuthorizationRepo : RepositoryBase<PER_ActionAuthorization>, IPER_ActionAuthorizationRepo
    {
        public void Allot(AuthorizationOwnerTypeEnum ownerType, int ownerId, IEnumerable<int> moduleIds, IEnumerable<int> functionIds)
        {
            using (var conn = CreateConn())
            {
                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        var db = GetIDataBase(conn);

                        var predicate = new PredicateGroup
                        {
                            Operator = GroupOperator.And,
                            Predicates = new List<IPredicate>
                            {
                                Predicates.Field<PER_ActionAuthorization>(f => f.OwnerType, Operator.Eq, ownerType),
                                Predicates.Field<PER_ActionAuthorization>(f => f.OwnerID, Operator.Eq, ownerId)
                            }
                        };
                        db.Delete<PER_ActionAuthorization>(predicate, trans);

                        List<PER_ActionAuthorization> authorizeItems = new List<PER_ActionAuthorization>();
                        foreach (var moduleId in moduleIds)
                        {
                            authorizeItems.Add(new PER_ActionAuthorization
                            {
                                OwnerType = ownerType,
                                OwnerID = ownerId,
                                ItemType = AuthorizationItemTypeEnum.Module,
                                ItemID = moduleId
                            });
                        }
                        foreach (var functionId in functionIds)
                        {
                            authorizeItems.Add(new PER_ActionAuthorization
                            {
                                OwnerType = ownerType,
                                OwnerID = ownerId,
                                ItemType = AuthorizationItemTypeEnum.Function,
                                ItemID = functionId
                            });
                        }
                        db.Insert<PER_ActionAuthorization>(authorizeItems, trans);

                        trans.Commit();
                    }
                    catch (Exception)
                    {
                        trans.Rollback();
                        throw;
                    }
                }
            }
        }

        public void Allot(AuthorizationOwnerTypeEnum ownerType, int ownerId, IEnumerable<int> moduleIds, IEnumerable<int> functionIds, Dictionary<string, IEnumerable<DataAuthorizationItemDTO>> dataAuthorizations)
        {
            using (var conn = CreateConn())
            {
                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        var db = GetIDataBase(conn);

                        var predicate = new PredicateGroup
                        {
                            Operator = GroupOperator.And,
                            Predicates = new List<IPredicate>
                            {
                                Predicates.Field<PER_ActionAuthorization>(f => f.OwnerType, Operator.Eq, ownerType),
                                Predicates.Field<PER_ActionAuthorization>(f => f.OwnerID, Operator.Eq, ownerId)
                            }
                        };
                        db.Delete<PER_ActionAuthorization>(predicate, trans);

                        List<PER_ActionAuthorization> authorizeItems = new List<PER_ActionAuthorization>();
                        foreach (var moduleId in moduleIds)
                        {
                            authorizeItems.Add(new PER_ActionAuthorization
                            {
                                OwnerType = ownerType,
                                OwnerID = ownerId,
                                ItemType = AuthorizationItemTypeEnum.Module,
                                ItemID = moduleId
                            });
                        }
                        foreach (var functionId in functionIds)
                        {
                            authorizeItems.Add(new PER_ActionAuthorization
                            {
                                OwnerType = ownerType,
                                OwnerID = ownerId,
                                ItemType = AuthorizationItemTypeEnum.Function,
                                ItemID = functionId
                            });
                        }
                        db.Insert<PER_ActionAuthorization>(authorizeItems, trans);
                        //数据权限
                        var dataAuthPredicate = new PredicateGroup
                        {
                            Operator = GroupOperator.And,
                            Predicates = new List<IPredicate>
                            {
                                Predicates.Field<PER_DataAuthorization>(f => f.OwnerType, Operator.Eq, ownerType),
                                Predicates.Field<PER_DataAuthorization>(f => f.OwnerID, Operator.Eq, ownerId)
                            }
                        };
                        db.Delete<PER_DataAuthorization>(dataAuthPredicate, trans);

                        List<PER_DataAuthorization> dataAuthorizeItems = new List<PER_DataAuthorization>();
                        foreach (var moduleDataAuthorizations in dataAuthorizations)
                        {
                            foreach (var moduleSingleDataAuthorization in moduleDataAuthorizations.Value)
                            {
                                if (moduleSingleDataAuthorization.CustomResourseIds != null && moduleSingleDataAuthorization.CustomResourseIds.Count > 0)
                                {
                                    foreach (var customResourseId in moduleSingleDataAuthorization.CustomResourseIds)
                                    {
                                        dataAuthorizeItems.Add(new PER_DataAuthorization
                                        {
                                            OwnerType = ownerType,
                                            OwnerID = ownerId,
                                            ModuleCode = moduleDataAuthorizations.Key,
                                            AuthorizationScope = moduleSingleDataAuthorization.AuthorizationScope,
                                            CustomResourceID = customResourseId,
                                            CreateTime = DateTime.Now,
                                            Creator = CurrentUser.Current.UserId
                                        });
                                    }
                                }
                                else
                                {
                                    dataAuthorizeItems.Add(new PER_DataAuthorization
                                    {
                                        OwnerType = ownerType,
                                        OwnerID = ownerId,
                                        ModuleCode = moduleDataAuthorizations.Key,
                                        AuthorizationScope = moduleSingleDataAuthorization.AuthorizationScope,
                                        CreateTime = DateTime.Now,
                                        Creator = CurrentUser.Current.UserId
                                    });
                                }
                            }
                        }
                        db.Insert<PER_DataAuthorization>(dataAuthorizeItems, trans);

                        trans.Commit();
                    }
                    catch (Exception)
                    {
                        trans.Rollback();
                        throw;
                    }
                }
            }
        }

    }
}
